package cn.zfs.springcloud.datasource.aspect;

import cn.zfs.springcloud.datasource.annotation.SwitchDataSource;
import cn.zfs.springcloud.datasource.contextholder.DataSourceContextHolder;
import cn.zfs.springcloud.datasource.init.InitData;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 切换数据源切面
 */
@SuppressWarnings({"Duplicates", "ReflectionForUnavailableAnnotation", "SpringAutowiredFieldsWarningInspection"})
@Aspect
@Component
@Order(2)
public class SwitchDataSourceAspect {

    private Logger logger = LoggerFactory.getLogger(SwitchDataSourceAspect.class);

    @Autowired
    private AspectPublic aspectPublic;
    @Autowired
    private InitData initData;

    // 设置切面
    @Pointcut("@annotation(cn.zfs.springcloud.datasource.annotation.SwitchDataSource)")
    public void switchDataSourcePointcut() {
    }


    @Before("switchDataSourcePointcut()")
    public void before(JoinPoint point) {
        Class<?> clazz = point.getTarget().getClass(); //获得当前访问的class
        String methodName = point.getSignature().getName(); //获得当前访问的方法名
        Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();//获得当前方法的参数的类型
        try {
            Method method = clazz.getMethod(methodName, argClass);//获得当前访问的方法对象
            logger.debug("判断是否存在@SwitchDataSource");
            if (method.isAnnotationPresent(SwitchDataSource.class)) {
                SwitchDataSource switchDataSource = method.getAnnotation(SwitchDataSource.class);
                aspectPublic.switchDataSource(switchDataSource.dataSourceName(), initData.getDefaultDataSourceName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @AfterReturning("switchDataSourcePointcut()")
    public void after() {
        DataSourceContextHolder.clearDetermineCurrentLookupKey();
    }

}
